<template>
  <a-card :bordered="false" title="商品分类" style="min-height: 100vh">
    <div class="table-page-search-wrapper">
      <a-form layout="inline">
        <a-row :gutter="24">
          <a-col :lg="2">
            <a-button type="primary" @click="handlerAdd" icon="plus">新增</a-button>
          </a-col>
          <!--          <a-col :lg="4">-->
          <!--            <a-form-item label="开启拖拽">-->
          <!--              <a-switch v-model="draggable" checked-children="开" un-checked-children="关" @change="onChange" />-->
          <!--            </a-form-item>-->
          <!--          </a-col>-->
        </a-row>
      </a-form>
    </div>
    <a-card :bordered="false">
      <div class="example" v-if="cardLoading">
        <a-spin />
      </div>
      <a-tree
        v-else
        class="draggable-tree"
        :draggable="draggable"
        :tree-data="categoryTreeList"
        :defaultExpandAll="false"
        @dragenter="onDragEnter"
        @drop="onDrop"
        :defaultExpandedKeys="defaultExpandedKeys"
      >
        <template #title="{ key: treeKey, title }">
          <a-dropdown :trigger="['contextmenu']">
            <span>{{ title }}</span>
            <template #overlay>
              <a-menu @click="({ key: menuKey }) => onContextMenuClick(treeKey, menuKey)">
                <a-menu-item key="1">删除</a-menu-item>
                <a-menu-item key="2">修改</a-menu-item>
              </a-menu>
            </template>
          </a-dropdown>
        </template>
      </a-tree>
    </a-card>
    <a-modal
      :title="modalTitle"
      :visible="modalVisible"
      :confirm-loading="confirmLoading"
      @ok="handleOk"
      @cancel="handleCancel"
    >
      <a-form-model
        ref="ruleForm"
        :model="form"
        :rules="rules"
        :label-col="labelCol"
        :wrapper-col="wrapperCol"
      >
        <a-form-model-item label="所属分类" v-if="form.parentId !== '0'">
          <a-tree-select
            v-model="form.parentId"
            :tree-data="categoryTreeList"
            placeholder="请选择所属分类"
            :treeDefaultExpandAll="false"
          >
          </a-tree-select>
        </a-form-model-item>
        <a-form-model-item label="分类名称" prop="name">
          <a-input placeholder="请输入分类名称" :allowClear="true" v-model="form.name" />
        </a-form-model-item>
      </a-form-model>
    </a-modal>
  </a-card>
</template>

<script>

import { getAction } from '@api/manage'
import { postAction } from '../../api/manage'

export default {
  created() {
    this.initCategoryTree()
  },
  data() {
    return {
      categoryTreeList: [],
      cardLoading: false,
      queryParam: {
        categoryName: undefined
      },
      draggable: false,
      editTag: false,
      modalTitle: '添加',
      modalVisible: false,
      confirmLoading: false,
      labelCol: { span: 4 },
      wrapperCol: { span: 14 },
      form: {
        parentId: undefined,
        name: '',
        id: undefined
      },
      defaultExpandedKeys: [],
      chooseExpandedKeys: [],
      rules: {
        name: [{ required: true, trigger: 'change', validator: this.verifyCategoryName }]
      },
      url: {
        getCategoryTree: '/product/category/getCategoryTree',
        deleteCategoryById: '/product/category/deleteCategoryById',
        verifyCategoryName: '/product/category/verifyCategoryName',
        getCategoryById: '/product/category/getCategoryById',
        editCategory: '/product/category/editCategory',
        addCategory: '/product/category/addCategory'
      }
    }
  },
  methods: {
    /**
     * 初始化分类树 数据
     */
    initCategoryTree() {
      this.cardLoading = true
      getAction(this.url.getCategoryTree, { categoryName: this.queryParam.categoryName }).then(res => {
        if (res.success) {
          this.categoryTreeList = res.result
        } else {
          this.$message.error(res.message)
        }
      }).finally(() => {
        this.cardLoading = false
      })
    },
    /**
     * 搜索
     */
    searchQuery() {
      this.initCategoryTree()
    },
    /**
     * 添加分类
     */
    handlerAdd() {
      this.modalVisible = true
      this.confirmLoading = false
    },
    /**
     * 表单确认
     */
    handleOk() {
      let that = this
      this.$refs.ruleForm.validate(valid => {
        if (valid) {
          that.confirmLoading = true
          that.modalVisible = false
          let url
          if (that.editTag) {
            url = that.url.editCategory
          } else {
            url = that.url.addCategory
          }
          postAction(url, that.form).then(res => {
            if (res.success) {
              that.$message.success(res.message)
              that.modalVisible = false
              that.confirmLoading = false
              that.initCategoryTree()
            } else {
              that.$message.error(res.message)
            }
          }).final(() => {
            that.editTag = false
            that.confirmLoading = false
            that.form.parentId = undefined
            that.form.name = ''
          })
        } else {
          that.$message.error('请检查表单项输入是否符合要求！')
        }
      })
    },
    /**
     * 表单取消
     */
    handleCancel() {
      this.modalVisible = false
      this.form.parentId = 0
      this.form.name = ''
      this.confirmLoading = false
    },
    /**
     * 开启拖拽
     */
    onChange() {
      let text = this.draggable ? '已开启拖拽！' : '已关闭拖拽！'
      this.$message.info(text)
    },
    /**
     * 校验分类名称是否重复
     */
    verifyCategoryName(rule, value, callback) {
      if (value === undefined || value === '') {
        return callback(new Error('请填写分类名称！'))
      }
      postAction(this.url.verifyCategoryName, this.form).then(res => {
        if (res.success) {
          callback()
        } else {
          return callback(new Error(res.message))
        }
      })
    },
    onContextMenuClick(treeKey, menuKey) {
      let id = treeKey
      let that = this
      if (menuKey === '1') {
        this.$confirm({
          title: '确定删除该分类极其子分类?',
          content: h => <div style="color:red;">删除后不可恢复</div>,
          onOk() {
            getAction(that.url.deleteCategoryById, { id: id }).then(res => {
              if (res.success) {
                that.$message.success(res.message)
                that.initCategoryTree()
              } else {
                that.$message.error(res.message)
              }
            })
          },
          onCancel() {
            that.$message.info('已取消删除！')
          },
          class: 'test'
        })
      } else {
        that.modalVisible = true
        that.editTag = true
        that.modalTitle = '修改'
        getAction(that.url.getCategoryById, { id: id }).then(res => {
          if (res.success) {
            that.form.id = id
            that.form.name = res.result.name
            that.form.parentId = res.result.parentId
          } else {
            that.$message.error(res.message)
          }
        })
      }
    },
    onDragEnter(info) {
      console.log(info)
    },
    onDrop(info) {
      const dropKey = info.node.eventKey
      const dragKey = info.dragNode.eventKey
      const dropPos = info.node.pos.split('-')
      const dropPosition = info.dropPosition - Number(dropPos[dropPos.length - 1])
      const loop = (data, key, callback) => {
        data.forEach((item, index, arr) => {
          if (item.key === key) {
            return callback(item, index, arr)
          }
          if (item.children) {
            return loop(item.children, key, callback)
          }
        })
      }
      const data = [...this.categoryTreeList]
      // Find dragObject
      let dragObj
      loop(data, dragKey, (item, index, arr) => {
        arr.splice(index, 1)
        dragObj = item
      })
      if (!info.dropToGap) {
        // Drop on the content
        loop(data, dropKey, item => {
          item.children = item.children || []
          // where to insert 示例添加到尾部，可以是随意位置
          item.children.push(dragObj)
        })
      } else if (
        (info.node.children || []).length > 0 && // Has children
        info.node.expanded && // Is expanded
        dropPosition === 1 // On the bottom gap
      ) {
        loop(data, dropKey, item => {
          item.children = item.children || []
          // where to insert 示例添加到尾部，可以是随意位置
          item.children.unshift(dragObj)
        })
      } else {
        let ar
        let i
        loop(data, dropKey, (item, index, arr) => {
          ar = arr
          i = index
        })
        if (dropPosition === -1) {
          ar.splice(i, 0, dragObj)
        } else {
          ar.splice(i + 1, 0, dragObj)
        }
      }
      this.categoryTreeList = data
    }
  }
}
</script>
<style scoped>
.example {
  text-align: center;
  border-radius: 4px;
  margin-bottom: 20px;
  padding: 30px 50px;
  margin: 20px 0;
}
</style>
